package com.dlc.shop.user.common.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.dlc.shop.bean.enums.ExcelErrorParam;
import com.dlc.shop.bean.model.ShopCustomer;
import com.dlc.shop.bean.model.User;
import com.dlc.shop.bean.param.*;
import com.dlc.shop.common.config.Constant;
import com.dlc.shop.common.exception.YamiShopBindException;
import com.dlc.shop.common.i18n.I18nMessage;
import com.dlc.shop.common.util.PageParam;
import com.dlc.shop.common.util.PoiExcelUtil;
import com.dlc.shop.common.util.PrincipalUtil;
import com.dlc.shop.service.ShopCustomerService;
import com.dlc.shop.service.UserService;
import com.dlc.shop.user.common.model.UserLevel;
import com.dlc.shop.user.common.service.UserGrowthLogService;
import com.dlc.shop.user.common.service.UserLevelService;
import com.dlc.shop.user.common.service.UserMemberService;
import com.dlc.shop.user.common.task.ListCustomerExportDataTask;
import com.dlc.shop.user.common.task.ListUserExportDataTask;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.*;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * @author lanhai
 */
@Slf4j
@Service
@AllArgsConstructor
public class UserMenberServiceImpl implements UserMemberService {

    private final UserService userService;
    private final ShopCustomerService shopCustomerService;
    private final UserLevelService userLevelService;
    private final UserGrowthLogService userGrowthLogService;
    private final ThreadPoolExecutor userThreadPoolExecutor;

    @Override
    public void exportUser(UserManagerReqParam userReqParam, HttpServletResponse response) {
        // 基础参数
        Long eachCount = 1000L;
        // 初始化
        PageParam<UserManagerParam> userPageParam = new PageParam<>();
        userPageParam.setCurrent(1);
        userPageParam.setSize(eachCount);
        IPage<UserManagerParam> userPage = userService.pageUserByMultiShop(userPageParam, userReqParam);
        long total = userPage.getTotal();
        // 多线程分页查询数据
        List<UserManagerParam> excelData = new ArrayList<>();
        if (total <= eachCount) {
            excelData = userPage.getRecords();
        } else {
            // 计算页数
            Integer pageSize = this.getPageSize(total, eachCount);
            // 多线程分页查询
            ExecutorService execservice = Executors.newFixedThreadPool(15);
            try {
                excelData.addAll(userPage.getRecords());
                List<Callable<List<UserManagerParam>>> tasks = new ArrayList<Callable<List<UserManagerParam>>>();
                for (int i = 2; i <= pageSize; i++) {
                    PageParam<UserManagerParam> page = new PageParam<>();
                    page.setCurrent(i);
                    page.setSize(eachCount);
                    ListUserExportDataTask task = new ListUserExportDataTask(userService, userReqParam, page);
                    tasks.add(task);
                }
                List<Future<List<UserManagerParam>>> futures = execservice.invokeAll(tasks);
                if (futures.size() > 0) {
                    for (Future<List<UserManagerParam>> future : futures) {
                        excelData.addAll(future.get());
                    }
                }
            } catch (Exception e) {
                System.out.println("多线程查询出现异常");
            } finally {
                execservice.shutdown();
            }
        }
        // 导出excel
        ExcelWriter writer = ExcelUtil.getBigWriter();
        String fileName = I18nMessage.getMessage("yami.excel.user.info") + ".xlsx";
        exportUserExcel(excelData, fileName, response, writer);
    }

    /**
     * 获取会员导出头
     * @return
     */
    private List<String> getUserHeads() {
        String[] headers = {
                I18nMessage.getMessage("yami.user.member.excel.header.memberName"),
                I18nMessage.getMessage("yami.user.member.excel.header.phone"),
                I18nMessage.getMessage("yami.user.member.excel.header.normalLevel"),
                I18nMessage.getMessage("yami.user.member.excel.header.growth"),
                I18nMessage.getMessage("yami.user.member.excel.header.status"),
                I18nMessage.getMessage("yami.user.member.excel.header.consAmount"),
                I18nMessage.getMessage("yami.user.member.excel.header.payAmount"),
                I18nMessage.getMessage("yami.user.member.excel.header.consTimes"),
                I18nMessage.getMessage("yami.user.member.excel.header.avgDiscount"),
                I18nMessage.getMessage("yami.user.member.excel.header.refundAmount"),
                I18nMessage.getMessage("yami.user.member.excel.header.refundTimes"),
                I18nMessage.getMessage("yami.user.member.excel.header.lastConsTime")
        };
        return Arrays.asList(headers);
    }

    /**
     * 导出店铺会员excel信息
     * @param excelData
     * @param fileName
     * @param response
     * @param writer
     */
    private void exportUserExcel(List<UserManagerParam> excelData, String fileName, HttpServletResponse response, ExcelWriter writer) {
        Sheet sheet = writer.getSheet();
        // 写入列头
        List<String> headers = this.getUserHeads();
        writer.merge(headers.size() - 1, I18nMessage.getMessage("yami.excel.user.info"));
        writer.writeRow(headers);
        // 设置列宽
        for (int i = 0; i < headers.size(); i++) {
            if (i == 19 || i == 20) {
                sheet.setColumnWidth(i, 30 * 256);
            } else {
                sheet.setColumnWidth(i, 20 * 256);
            }
        }
        // 如果要导出的数据为空，导出一个模板
        if (CollectionUtils.isEmpty(excelData)) {
            PoiExcelUtil.writeExcel(response, writer);
            return;
        }
        int row = 2;
        for (UserManagerParam param : excelData) {
            // 状态
            String status = param.getStatus() == 0 ? I18nMessage.getMessage("yami.user.member.status.disable") : I18nMessage.getMessage("yami.user.member.status.normal");
            Object[] colData = {
                    param.getMemberName(),
                    param.getUserMobile(),
                    param.getShopLevelType() == 0 ? param.getShopLevelName() : "",
                    param.getGrowth(),
                    status,
                    param.getConsAmount(),
                    param.getActualAmount(),
                    param.getConsTimes(),
                    param.getAverDiscount(),
                    param.getAfterSaleAmount(),
                    param.getAfterSaleTimes(),
                    Objects.nonNull(param.getUserRegtime()) ? DateUtil.format(param.getReConsTime(), "yyyy-MM-dd HH:mm:ss") : ""
            };
            for (int i=0; i<colData.length; i++) {
                PoiExcelUtil.mergeIfNeed(writer, row, row, i, i, colData[i]);
            }
            row++;
        }
        PoiExcelUtil.writeExcel(fileName, writer, response);
    }

    @Override
    public void exportCustomer(CustomerManagerParam customerParam, HttpServletResponse response) {
        // 基础参数
        Long eachCount = 1000L;
        // 初始化
        PageParam<CustomerManagerParam> customerPageParam = new PageParam<>();
        customerPageParam.setCurrent(1);
        customerPageParam.setSize(eachCount);
        IPage<CustomerManagerParam> customerPage = userService.pageCustomerByMultiShop(customerPageParam, customerParam);
        long total = customerPage.getTotal();
        // 多线程分页查询数据
        List<CustomerManagerParam> excelData = new ArrayList<>();
        if (total <= eachCount) {
            excelData = customerPage.getRecords();
        } else {
            // 计算页数
            Integer pageSize = this.getPageSize(total, eachCount);
            // 多线程分页查询
            try {
                excelData.addAll(customerPage.getRecords());
                List<Callable<List<CustomerManagerParam>>> tasks = new ArrayList<>();
                for (int i = 2; i <= pageSize; i++) {
                    PageParam<CustomerManagerParam> page = new PageParam<>();
                    page.setCurrent(i);
                    page.setSize(eachCount);
                    ListCustomerExportDataTask task = new ListCustomerExportDataTask(userService, customerParam, page);
                    tasks.add(task);
                }
                List<Future<List<CustomerManagerParam>>> futures = userThreadPoolExecutor.invokeAll(tasks);
                if (futures.size() > 0) {
                    for (Future<List<CustomerManagerParam>> future : futures) {
                        excelData.addAll(future.get());
                    }
                }
            } catch (Exception e) {
                System.out.println("多线程查询出现异常");
            }
        }
        // 导出excel
        ExcelWriter writer = ExcelUtil.getBigWriter();
        String fileName = "客户信息.xlsx";
        exportCustomerExcel(excelData, fileName, response, writer);
    }

    /**
     * 客户信息 - excel导出
     * @param excelData
     * @param fileName
     * @param response
     * @param writer
     */
    private void exportCustomerExcel(List<CustomerManagerParam> excelData, String fileName, HttpServletResponse response, ExcelWriter writer) {
        Sheet sheet = writer.getSheet();
        // 写入列头
        List<String> headers = getCustomerHeads();
        writer.merge(headers.size() - 1, "客户信息");
        writer.writeRow(headers);
        // 设置列宽
        for (int i = 0; i < headers.size(); i++) {
            if (i == 19 || i == 20) {
                sheet.setColumnWidth(i, 30 * 256);
            } else {
                sheet.setColumnWidth(i, 20 * 256);
            }
        }
        // 如果要导出的数据为空，导出一个模板
        if (CollectionUtils.isEmpty(excelData)) {
            PoiExcelUtil.writeExcel(response, writer);
            return;
        }
        int row = 2;
        for (CustomerManagerParam param : excelData) {
            Object[] colData = {
                    param.getNickName(),
                    param.getUserMobile(),
                    param.getTotalOrderTimes(),
                    param.getConsTimes(),
                    param.getConsAmount(),
                    param.getActualAmount(),
                    param.getAverDiscount(),
                    param.getAfterSaleTimes(),
                    param.getAfterSaleAmount()
            };
            for (int i=0; i<colData.length; i++) {
                PoiExcelUtil.mergeIfNeed(writer, row, row, i, i, colData[i]);
            }
            row++;
        }
        PoiExcelUtil.writeExcel(fileName, writer, response);
    }

    /**
     * 获取客户导出头
     * @return
     */
    private List<String> getCustomerHeads() {
        String[] headers = {
                I18nMessage.getMessage("yami.user.customer.excel.header.nickName"),
                I18nMessage.getMessage("yami.user.customer.excel.header.phone"),
                I18nMessage.getMessage("yami.user.customer.excel.header.orderNumber"),
                I18nMessage.getMessage("yami.user.customer.excel.header.consNumber"),
                I18nMessage.getMessage("yami.user.customer.excel.header.consAmount"),
                I18nMessage.getMessage("yami.user.customer.excel.header.payAmount"),
                I18nMessage.getMessage("yami.user.customer.excel.header.avgDiscount"),
                I18nMessage.getMessage("yami.user.customer.excel.header.refundTimes"),
                I18nMessage.getMessage("yami.user.customer.excel.header.refundAmount")
        };
        return Arrays.asList(headers);
    }

    /**
     * 计算获取分页页数
     * @param total
     * @param eachCount
     * @return
     */
    private Integer getPageSize(Long total, Long eachCount) {
        int pageSize = new BigDecimal(total).divide(new BigDecimal(eachCount), RoundingMode.DOWN).intValue();
        int mod = new BigDecimal(total).divideAndRemainder(new BigDecimal(eachCount))[1].intValue();
        if (mod > 0) {
            pageSize = pageSize + 1;
        }
        return pageSize;
    }

    @Override
    public void downloadTemplate(Integer templateType, HttpServletResponse response) {
        List<String> headers = this.getDownloadHeader(templateType);
        // excel写入表头
        ExcelWriter writer = ExcelUtil.getBigWriter();
        Sheet sheet = writer.getSheet();
        writer.writeRow(headers);
        // 列表设置为文本格式，以及列宽
        CellStyle style = writer.createCellStyle();
        try (Workbook workbook = writer.getWorkbook()) {
            DataFormat format = workbook.createDataFormat();
            style.setDataFormat(format.getFormat("@"));
            for (int i = 0; i < headers.size(); i++) {
                boolean verdict = 1 == templateType && (i == 4 || i == 5);
                    if (verdict) {
                        sheet.setColumnWidth(i, 60 * 256);
                    } else {
                        sheet.setColumnWidth(i, 20 * 256);
                    }
                    sheet.setDefaultColumnStyle(i, style);
            }
            // 导出excel
            PoiExcelUtil.writeExcel(response, writer);
        } catch (Exception e) {
            log.error("下载会员导入模板错误:", e);
        }
    }

    /**
     * 获取下载模板的表头
     * @param templateType 模板类型
     * @return
     */
    private List<String> getDownloadHeader(Integer templateType) {
        List<String> headers;
        if (0 == templateType) {
            // 客户表头
            headers = Arrays.asList(
                    I18nMessage.getMessage("yami.user.customer.excel.template.header.seq"),
                    I18nMessage.getMessage("yami.user.customer.excel.template.header.phone")
            );
        } else if (1 == templateType) {
            // 会员表头
            headers = Arrays.asList(
                    I18nMessage.getMessage("yami.user.member.excel.template.header.seq"),
                    I18nMessage.getMessage("yami.user.member.excel.template.header.memberName"),
                    I18nMessage.getMessage("yami.user.member.excel.template.header.phone"),
                    I18nMessage.getMessage("yami.user.member.excel.template.header.growth")
            );
        } else {
            throw new YamiShopBindException("错误模板类型");
        }
        return headers;
    }

    @Override
    public UserExcelParam importCustomer(Long shopId, MultipartFile excelFile) throws IOException {
        return this.importExcel(shopId, 0, excelFile);
    }

    @Override
    public UserExcelParam importUser(Long shopId, MultipartFile excelFile) throws IOException {
        return this.importExcel(shopId, 1, excelFile);
    }

    /**
     * 客户/会员通用excel导入
     * @param shopId
     * @param importType
     * @param excelFile
     * @return
     */
    private UserExcelParam importExcel(Long shopId, Integer importType, MultipartFile excelFile) {
        Integer lang = I18nMessage.getDbLang();
        UserExcelParam resParam = new UserExcelParam();
        resParam.setSuccess(false);
        resParam.setImmediately(false);
        try (InputStream inputStream = excelFile.getInputStream();
             Workbook workBook = WorkbookFactory.create(inputStream)) {
            if (importType == 1) {
                // 判断是否存在会员等级，不存在需创建一个默认会员等级，才能继续会员导入
                long levelCount = userLevelService.count(new LambdaQueryWrapper<UserLevel>()
                        .eq(UserLevel::getLevelType, 0)
                        .eq(UserLevel::getShopId, shopId));
                if (levelCount == 0) {
                    throw new YamiShopBindException("yami.user.level.default.no.exist");
                }
            }
            // * 2.1不是Excel文件，直接返回提示信息
            if (!(excelFile.getOriginalFilename().contains(Constant.XLS_FILE) || excelFile.getOriginalFilename().contains(Constant.XLSX_FILE))) {
                // 格式错误
                throw new YamiShopBindException("yami.file.error");
            }
            //读取工作表
            Sheet sheet = workBook.getSheetAt(0);
            int rowNums = sheet.getPhysicalNumberOfRows();
            // 检查模板格式
            this.checkExcelHeader(sheet.getRow(0), importType);
            //校验是否填写内容
            if (rowNums <= 1) {
                // 文件无内容
                throw new YamiShopBindException("yami.document.no.content");
            }
            Set<String> phoneSet = new HashSet<>();
            List<ExcelErrorParam> errorRows = new ArrayList<>();
            List<UserRegisterExcelParam> excelParams = new ArrayList<>();
            //循环读取每一行数据并校验
            for (int i = 1; i < rowNums; i++) {
                try {
                    Row row = sheet.getRow(i);
                    UserRegisterExcelParam excelParam;
                    // 0读取客户数据，1读取会员数据，最终结果都是封装在UserRegisterExcelParam此类中
                    if (importType == 0) {
                        excelParam = this.getCustomerExcelParam(row, errorRows, phoneSet);
                    } else {
                        excelParam = this.getUserExcelParam(row, errorRows, phoneSet);
                    }
                    if (excelParam != null) {
                        excelParams.add(excelParam);
                    }
                } catch (Exception e) {
                    resParam.setRow(i + 1);
                    resParam.setMsg(String.format(I18nMessage.getMessage("yami.common.excel.import.line.error"), i, e.getMessage()));
                    resParam.setImmediately(true);
                    return resParam;
                }
            }
            // 将数据新增/更新到数据库中
            if (CollectionUtils.isNotEmpty(excelParams)) {
                resParam = this.saveOrUpdateBatchExcel(errorRows, excelParams, phoneSet, shopId, importType);
            } else {
                resParam.setSuccessNum(0);
                resParam.setErrorNum(errorRows.size());
            }
            this.buildImportResult(rowNums-1, excelParams.size(), errorRows, resParam);
            return resParam;
        } catch (Exception e) {
            resParam.setMsg(e.getMessage());
            resParam.setImmediately(true);
            return resParam;
        }
    }

    /**
     * 检查excel表头（判断是否是合法的导入模板文件）
     * @param row 表头
     * @param importType 导入类型
     */
    private void checkExcelHeader(Row row, Integer importType) {
        List<String> headers = this.getDownloadHeader(importType);
        for (int i=0; i<headers.size(); i++) {
            if (!Objects.equals(headers.get(i), PoiExcelUtil.getRowValue(row, i, false))) {
                throw new YamiShopBindException("yami.file.template.error");
            }
        }
    }

    /**
     * 获取客户excel数据
     * @param row
     * @param errorRows
     * @param phoneSet
     * @return
     */
    private UserRegisterExcelParam getCustomerExcelParam(Row row, List<ExcelErrorParam> errorRows, Set<String> phoneSet) {
        int cell = 0;
        // 序号
        String serialNo = PoiExcelUtil.getRowValue(row, cell, false);
        serialNo = ObjectUtils.isEmpty(serialNo) ? String.valueOf(row.getRowNum()) : serialNo;
        // 电话号码
        String phone = PoiExcelUtil.getRowValue(row, ++cell, false);
        // 数据出错，不往下执行
        if (!checkCustomerData(errorRows, phoneSet, serialNo, phone)){
            return null;
        }
        phoneSet.add(phone);
        // 构建数据
        UserRegisterExcelParam excelParam = new UserRegisterExcelParam();
        excelParam.setSerialNo(serialNo);
        excelParam.setPhone(phone);
        return excelParam;
    }

    /**
     * 获取会员excel数据
     * @param row
     * @param errorRows
     * @param phoneSet
     * @return
     */
    private UserRegisterExcelParam getUserExcelParam(Row row, List<ExcelErrorParam> errorRows, Set<String> phoneSet) {
        int cell = 0;
        // 序号
        String serialNo = PoiExcelUtil.getRowValue(row, cell, false);
        serialNo = ObjectUtils.isEmpty(serialNo) ? String.valueOf(row.getRowNum()) : serialNo;
        // 用户昵称
        String nickName = PoiExcelUtil.getRowValue(row, ++cell, false);
        // 电话号码
        String phone = PoiExcelUtil.getRowValue(row, ++cell, false);
        // 成长值
        String growth = PoiExcelUtil.getRowValue(row, ++cell, false);
        // 数据出错，不往下执行
        if (!this.checkCustomerData(errorRows, phoneSet, serialNo, phone)){
            return null;
        }
        if (!this.checkUserExcelData(errorRows, serialNo, growth)) {
            return null;
        }
        phoneSet.add(phone);
        // 构建数据
        UserRegisterExcelParam excelParam = new UserRegisterExcelParam();
        excelParam.setSerialNo(serialNo);
        excelParam.setNickName(nickName);
        excelParam.setPhone(phone);
        excelParam.setGrowth(growth == null ? 0 :Integer.parseInt(growth));
        excelParam.setLevelType(0);
        return excelParam;
    }

    /**
     * 检查客户数据
     * @param errorRows
     * @param phoneSet
     * @param serialNo
     * @param phone
     * @return
     */
    private boolean checkCustomerData(List<ExcelErrorParam> errorRows, Set<String> phoneSet, String serialNo, String phone) {
        if (ObjectUtils.isEmpty(phone)) {
            errorRows.add(new ExcelErrorParam(
                    Integer.parseInt(serialNo),
                    1,
                    phone,
                    I18nMessage.getMessage("yami.user.member.customer.excel.import.phone.null")));
            return false;
        }
        if (!PrincipalUtil.isMobile(phone)) {
            errorRows.add(new ExcelErrorParam(
                    Integer.parseInt(serialNo),
                    1,
                    phone,
                    I18nMessage.getMessage("yami.user.member.customer.excel.import.phone.error")));
            return false;
        }
        if (phoneSet.contains(phone)) {
            errorRows.add(new ExcelErrorParam(
                    Integer.parseInt(serialNo),
                    1,
                    phone,
                    I18nMessage.getMessage("yami.user.member.customer.excel.import.phone.repeat")));
            return false;
        }
        return true;
    }

    /**
     * 检查会员数据
     * @param errorRows 错误行信息
     * @param serialNo 序号
     * @param growth 成长值
     * @return
     */
    private boolean checkUserExcelData(List<ExcelErrorParam> errorRows,
                                       String serialNo,
                                       String growth) {
        if (!ObjectUtils.isEmpty(growth)) {
            try {
                Integer.parseInt(growth);
            } catch (NumberFormatException e) {
                errorRows.add(new ExcelErrorParam(
                        Integer.parseInt(serialNo),
                        2,
                        growth,
                        I18nMessage.getMessage("yami.user.member.customer.excel.import.growth.mustInt")));
                return false;
            }
        }
        return true;
    }



    /**
     * 更新或保存excel数据
     * @param errorRows
     * @param excelParams
     * @param phoneSet
     * @param shopId
     * @return
     */
    private UserExcelParam saveOrUpdateBatchExcel(List<ExcelErrorParam> errorRows,
                                                  List<UserRegisterExcelParam> excelParams,
                                                  Set<String> phoneSet,
                                                  Long shopId,
                                                  Integer importType) {
        List<User> users = userService.list(new LambdaQueryWrapper<User>()
                .in(User::getUserMobile, phoneSet));
        UserExcelParam userExcelParam = new UserExcelParam();
        boolean isMemberImport = Objects.equals(1, importType);
        // 没有关联的用户信息，直接返回
        if (users.isEmpty()) {
            for (UserRegisterExcelParam param : excelParams) {
                errorRows.add(new ExcelErrorParam(
                        Integer.parseInt(param.getSerialNo()),
                        1,
                        param.getPhone(),
                        I18nMessage.getMessage("yami.user.member.customer.excel.import.user.notExist")));
            }
            userExcelParam.setSuccessNum(0);
            return userExcelParam;
        }
        // 查询该店铺中已存在的客户，用作数据过滤
        List<String> userIds = users.stream().map(User::getUserId).collect(Collectors.toList());
        List<ShopCustomer> customers = shopCustomerService.list(new LambdaQueryWrapper<ShopCustomer>()
                .eq(ShopCustomer::getShopId, shopId)
                .in(ShopCustomer::getUserId, userIds));
        Map<String, ShopCustomer> userIdCustomerMap = customers.stream().collect(Collectors.toMap(ShopCustomer::getUserId, sc -> sc));
        // 查询店铺会员等级（会员导入需要）
        List<UserLevel> freeLevels = new ArrayList<>();
        if (1 == importType) {
            freeLevels = userLevelService.list(new LambdaQueryWrapper<UserLevel>()
                    .eq(UserLevel::getShopId, shopId)
                    .eq(UserLevel::getLevelType, 0)
                    .orderByDesc(UserLevel::getNeedGrowth));
        }
        // 用电话作为唯一关联，判断用户是否存在
        List<ShopCustomer> saveData = new ArrayList<>(16);
        List<Long> deleteIds = new ArrayList<>(16);
        // 处理excel数据
        int successNum = handleExcelParam(excelParams, users, errorRows, userIdCustomerMap, shopId, isMemberImport, deleteIds, saveData, freeLevels);

        // excel数据保存进数据库
        if (!CollectionUtils.isEmpty(deleteIds)) {
            shopCustomerService.removeByIds(deleteIds);
        }
        if (!CollectionUtils.isEmpty(saveData)) {
            shopCustomerService.saveBatch(saveData);
        }
        userExcelParam.setSuccessNum(successNum);
        return userExcelParam;
    }

    private int handleExcelParam(List<UserRegisterExcelParam> excelParams, List<User> users, List<ExcelErrorParam> errorRows, Map<String, ShopCustomer> userIdCustomerMap,
                                 Long shopId, boolean isMemberImport, List<Long> deleteIds, List<ShopCustomer> saveData, List<UserLevel> freeLevels) {
        User user;
        ShopCustomer shopCustomer;
        Map<String, User> phoneUserMap = users.stream().collect(Collectors.toMap(User::getUserMobile, x -> x));
        int successNum = 0;
        for (UserRegisterExcelParam excelParam : excelParams) {
            shopCustomer = null;
            user = phoneUserMap.get(excelParam.getPhone());
            if (user == null) {
                errorRows.add(new ExcelErrorParam(
                        Integer.parseInt(excelParam.getSerialNo()),
                        1,
                        excelParam.getPhone(),
                        I18nMessage.getMessage("yami.user.member.customer.excel.import.user.notExist")));
                continue;
            }
            // 已存在数据，进行进一步判断是否导入
            if (userIdCustomerMap.containsKey(user.getUserId())) {
                shopCustomer = userIdCustomerMap.get(user.getUserId());
                // 是会员导入，且导入的用户为非会员，直接删除用户，在后面的步骤新增回来
                if (isMemberImport && Objects.equals(-1, shopCustomer.getLevelType())) {
                    deleteIds.add(shopCustomer.getShopCustomerId());
                    shopCustomer.setShopCustomerId(null);
                } else {
                    errorRows.add(new ExcelErrorParam(
                            Integer.parseInt(excelParam.getSerialNo()),
                            0,
                            excelParam.getPhone(),
                            I18nMessage.getMessage("yami.user.member.customer.excel.import.phone.exist")));
                    continue;
                }
            }
            if (shopCustomer == null) {
                shopCustomer = new ShopCustomer();
                shopCustomer.setUserId(user.getUserId());
                shopCustomer.setMemberName(user.getNickName());
                shopCustomer.setShopId(shopId);
                shopCustomer.setLevelType(-1);
                shopCustomer.setGrowth(0);
            }
            // 会员导入shopCustomer需要额外补充数据
            if (isMemberImport) {
                shopCustomer.setLevelType(0);
                UserLevel userLevel = getLevelByGrowth(excelParam.getGrowth(), freeLevels);
                if (userLevel != null) {
                    shopCustomer.setLevelId(userLevel.getId());
                    shopCustomer.setLevel(userLevel.getLevel());
                }
                shopCustomer.setGrowth(excelParam.getGrowth());
                shopCustomer.setRegistTime(new Date());
            }
            saveData.add(shopCustomer);
            successNum++;
        }
        return successNum;
    }

    /**
     * 根据成长值获取合适的会员等级
     * @param growth
     * @param levels
     * @return
     */
    private UserLevel getLevelByGrowth(Integer growth, List<UserLevel> levels) {
        if (CollectionUtils.isEmpty(levels)) {
            return null;
        }
        for (UserLevel level : levels) {
            if (growth.compareTo(level.getNeedGrowth()) >= 0) {
                return level;
            }
        }
        return levels.get(levels.size()-1);
    }

    /**
     * 构建excel导入结果信息
     * @param userExcelParam
     * @return
     */
    public void buildImportResult(Integer totalRowNum,
                                    Integer paramSize,
                                    List<ExcelErrorParam> errorRows,
                                    UserExcelParam userExcelParam) {
        // 获取Excel基本信息
        String normalInfo = String.format(I18nMessage.getMessage("yami.user.member.customer.excel.import.normalInfo"), totalRowNum, paramSize, totalRowNum-paramSize);
        // 获取系统已存在的数据信息
        Map<Integer, List<ExcelErrorParam>> errorRowMap = errorRows.stream().collect(Collectors.groupingBy(ExcelErrorParam::getErrorType));
        String existPhoneInfo = "";
        if (errorRowMap.get(0) != null) {
            Set<String> phones = errorRowMap.get(0).stream().map(ExcelErrorParam::getData).collect(Collectors.toSet());
            existPhoneInfo = String.format(I18nMessage.getMessage("yami.user.member.customer.excel.import.existPhoneInfo"), errorRowMap.get(0).size(), phones);
        }
        String notExistPhoneInfo = "";
        if(errorRowMap.get(1) != null){
            Set<String> phones = errorRowMap.get(1).stream().map(ExcelErrorParam::getData).collect(Collectors.toSet());
            notExistPhoneInfo = String.format(I18nMessage.getMessage("yami.user.member.customer.excel.import.notExistPhoneInfo"), errorRowMap.get(1).size(), phones);
        }
        // 获取Excel导入信息
        String importInfo = String.format(I18nMessage.getMessage("yami.user.member.customer.excel.import.importInfo"), userExcelParam.getSuccessNum(), paramSize - userExcelParam.getSuccessNum());
        // 补充数据
        userExcelParam.setMsg(normalInfo + existPhoneInfo + notExistPhoneInfo + importInfo);
        userExcelParam.setErrorNum(errorRows.size());
        if (!CollectionUtils.isEmpty(errorRows)) {
            userExcelParam.setErrorRowInfos(errorRows.stream().sorted(Comparator.comparingInt(ExcelErrorParam::getRowNum)).map(ExcelErrorParam::getErrorMsg).collect(Collectors.toList()));
        } else {
            userExcelParam.setErrorRowInfos(new ArrayList<>());
        }
    }
}
